import xml.etree.cElementTree as ET

# Code is based on http://code.activestate.com/recipes/573463/
def _convert_dict_to_xml_recurse(parent, dictitem, listnames):
    """Helper Function for XML conversion."""
    # we can't convert bare lists
    assert not isinstance(dictitem, list)

    if isinstance(dictitem, dict):
        for (tag, child) in sorted(dictitem.iteritems()):
            if isinstance(child, list):
                # iterate through the array and convert
                listelem = ET.Element(tag)
                parent.append(listelem)
                # determine the child'stag name
                childTag = tag
                for m ,s in [('ies', 'y'), ('s', '')]:
                  if childTag.endswith(m):
                    childTag = childTag[:-len(m)]+s  
                    break
                if childTag == tag:
                  childTag = listnames.get(tag, 'object')
                # finally iter
                for listchild in child:
                    elem = ET.Element(childTag)
                    listelem.append(elem)
                    _convert_dict_to_xml_recurse(elem, listchild, listnames)
            elif tag == 'id':
              parent.attrib['id'] = unicode(child)
            elif tag == 'name':
              parent.attrib['name'] = unicode(child)
            elif tag.find('/') != -1:
                elem = ET.Element(listnames.get(tag, 'object'))
                parent.append(elem)
                elem.attrib['name'] = unicode(tag)
                _convert_dict_to_xml_recurse(elem, child, listnames)
            else:
                elem = ET.Element(tag)
                parent.append(elem)
                _convert_dict_to_xml_recurse(elem, child, listnames)
    elif not dictitem is None:
        parent.text = unicode(dictitem)


# From http://effbot.org/zone/element-lib.htm
def prettyprint(elem, indent=1, level=0):
    """XML prettyprint: Prints a tree with each node indented according to its depth."""
    i = "\n" + ((level*indent) * " ")
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + (" "*indent)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for child in elem:
            prettyprint(child, indent, level+1)
        if child:
            if not child.tail or not child.tail.strip():
                child.tail = i
            if not elem.tail or not elem.tail.strip():
                elem.tail = i 
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i


def dumps(data, indent=None):
  def dict2et(data, node):
    root = ET.Element(node)
    _convert_dict_to_xml_recurse(root, data, {})
    return root
  if isinstance(data, list):
    tree = dict2et({'objects': data}, 'xml').find('objects')
  elif isinstance(data, dict):
    tree = dict2et(data, 'root')
  if indent:
    prettyprint(tree, indent=indent)
  return ET.tostring(tree, 'utf-8')

  
if __name__ == '__main__':
  data = {"daemons": [{'status': 'Running', 'info': 'mem usage', 'workers': 2},], 'info': [{'blah':1}]}
  print dumps(data, indent=4)
  data = [{'id': 1, 'status': 'Running', 'info': 'mem usage', 'workers': 2}, {'status': 'Stopped', 'info': 'mem usage', 'workers': 1}, ]
  print dumps(data, indent=4)


